/*
 * CCVisu is a tool for visual graph clustering
 * and general force-directed graph layout.
 * This file is part of CCVisu. 
 *
 * Copyright (C) 2005-2012  Dirk Beyer
 *
 * CCVisu is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * CCVisu is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with CCVisu; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Please find the GNU Lesser General Public License in file
 * license_lgpl.txt or http://www.gnu.org/licenses/lgpl.txt
 *
 * Dirk Beyer    (firstname.lastname@uni-passau.de)
 * University of Passau, Bavaria, Germany
 */
package org.sosy_lab.util;

import java.util.Collection;
import java.util.LinkedList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import org.sosy_lab.util.interfaces.ProgressReceiver;
import org.sosy_lab.util.interfaces.Progressing;
import org.sosy_lab.util.interfaces.WorkerManager;

public class CCVisuWorkerManager implements WorkerManager {

  private ExecutorService executorService = null;
  private Collection<ProgressReceiver> receivers = new LinkedList<ProgressReceiver>();

  @Override
  public void cancelActiveWorkerThreads() {
    synchronized (this) {
      if (executorService != null) {
        executorService.shutdownNow();
        try {
          executorService.awaitTermination(5, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
        }
        executorService = null;
      }
    }

    for (ProgressReceiver receiver : receivers) {
      receiver.processChange(this, 0, 0, "");
    }
  }

  /**
   * Add a task that can provide progress information
   * to the executor service.
   */
  @Override
  public <T extends Runnable & Progressing> void addAndRunTask(T task, String name) {
    for (ProgressReceiver receiver : receivers) {
      task.addProgressReceiver(receiver);
    }

    synchronized (this) {
      if (executorService == null) {
        executorService = Executors.newFixedThreadPool(1);
      }
      executorService.execute(task);
    }
  }

  @Override
  public void addReceiver(ProgressReceiver receiver) {
    assert receiver != null;
    receivers.add(receiver);
  }
}